import { useState } from "react"

const KeysListDemo = () => {
  const [items, setItems] = useState([
    { id: 1, text: "Item 1" },
    { id: 2, text: "Item 2" },
    { id: 3, text: "Item 3" }
  ])

  const [inputValues, setInputValues] = useState<Record<number, string>>({
    1: "", 2: "", 3: ""
  })

  const [index, setIndex] = useState(4)

  // 使用索引作为key的示例
  const renderWithIndex = () => {
    return (
      <div>
        <h4>使用索引作为key:</h4>
        <ul>
          {items.map((item, index) => (
            <li key={index}>
              <span>{item.text}</span>
              <input 
                type="text" 
                placeholder="输入内容..." 
                value={inputValues[item.id] || ""}
                onChange={(e) => setInputValues({
                  ...inputValues,
                  [item.id]: e.target.value
                })}
              />
            </li>
          ))}
        </ul>
      </div>
    )
  }

  // 使用ID作为key的示例
  const renderWithId = () => {
    return (
      <div>
        <h4>使用ID作为key:</h4>
        <ul>
          {items.map(item => (
            <li key={item.id}>
              <span>{item.text}</span>
              <input 
                type="text" 
                placeholder="输入内容..." 
                value={inputValues[item.id] || ""}
                onChange={(e) => setInputValues({
                  ...inputValues,
                  [item.id]: e.target.value
                })}
              />
            </li>
          ))}
        </ul>
      </div>
    )
  }

  // 添加新项目到列表前面 - 会导致使用索引作为key的情况出问题
  const addItemToBeginning = () => {
    const newItem = { id: index, text: `Item ${index}` }
    setItems([newItem, ...items])
    setIndex(index + 1)
  }

  // 重新排序项目 - 会导致使用索引作为key的情况出问题
  const shuffleItems = () => {
    const shuffled = [...items].sort(() => Math.random() - 0.5)
    setItems(shuffled)
  }

  return (
    <div className="demo-section">
      <h2>列表和Keys面试题讲解</h2>

      <div className="card">
        <h3>1. 什么是Keys，为什么需要Keys?</h3>
        <p>
          Keys 是 React 用来标识列表项目的特殊属性，帮助 React 识别哪些项目已经更改、添加或删除。
          Keys 应该是稳定、可预测且唯一的标识符。
        </p>
        <div className="code-example">
          <code>{`{items.map(item => (
  <li key={item.id}>{item.text}</li>
))}`}</code>
        </div>
      </div>

      <div className="card">
        <h3>2. 常见面试问题: 为什么不推荐使用索引作为Key?</h3>
        <p>
          使用索引作为key会导致以下问题:
        </p>
        <ul>
          <li>当列表项目顺序变化时，组件状态可能会出错</li>
          <li>在列表前面插入新项目会导致所有已有项目的索引变化，引起不必要的重新渲染</li>
          <li>可能会破坏组件状态或导致输入框等受控组件状态混乱</li>
        </ul>

        <div className="example-output">
          <p>尝试在这两个列表中输入一些文本，然后点击按钮添加新项目或打乱顺序：</p>
          <button onClick={addItemToBeginning}>在列表前添加项目</button>
          <button onClick={shuffleItems}>打乱列表顺序</button>
          
          <div className="flex-container">
            <div className="flex-item">
              {renderWithIndex()}
            </div>
            <div className="flex-item">
              {renderWithId()}
            </div>
          </div>
          <p className="warning">
            注意: 当添加新项目或重新排序时，使用索引作为key的列表会出现输入框状态错乱的问题，
            而使用ID作为key的列表则能正确保持每个输入框的状态。
          </p>
        </div>
      </div>

      <div className="card">
        <h3>3. 什么时候可以使用索引作为Key?</h3>
        <p>
          只有在以下所有条件都满足的情况下，才可以考虑使用索引作为key:
        </p>
        <ul>
          <li>列表是静态的，不会重新计算或更改</li>
          <li>列表项没有ID</li>
          <li>列表永远不会重新排序或筛选</li>
          <li>列表项不包含状态（如输入框）</li>
        </ul>
      </div>

      <div className="card">
        <h3>4. 面试核心要点</h3>
        <ul>
          <li>Keys应该是唯一且稳定的，最好使用服务端生成的ID</li>
          <li>Keys只需要在兄弟节点之间唯一，不需要全局唯一</li>
          <li>不要使用随机值作为Keys，因为每次渲染会生成不同的值</li>
          <li>如果没有稳定的ID，可以考虑使用item.id、item.name或将多个字段组合起来</li>
          <li>使用不当的Keys会导致性能问题和状态管理错误</li>
        </ul>
      </div>
    </div>
  )
}

export default KeysListDemo 